package com.wquick.base.shatter


import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.annotation.LayoutRes
import androidx.asynclayoutinflater.view.AsyncLayoutInflater
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.coroutineScope
import androidx.viewbinding.ViewBinding


/**
 * 具体的一个XML的View的子碎片
 * 它作为碎片的基类，提供了一些生命周期方法和管理子碎片的功能
 */
abstract class Shatter : ShatterLifecycleListener, LifecycleOwner {

    var shatterManager: ShatterManager? = null
    var containView: View? = null
    var thisView: View? = null
    private var lifecycleOwner: LifecycleOwner? = null
    private var preloadedView: View? = null
    private var isPreloading: Boolean = false
    private var isPreloadCompleted: Boolean = false
    private var onViewReadyListener: OnViewReadyListener? = null

    interface OnViewReadyListener {
        fun onViewReady(view: View)
    }

    val lifecycleScope: LifecycleCoroutineScope?
        get() = lifecycleOwner?.lifecycle?.coroutineScope

    @PublishedApi
    internal var viewBinding: ViewBinding? = null

    /** 获取ViewBinding实例 **/
    inline fun <reified B : ViewBinding> getBinding(): B {
        return if (viewBinding == null) {
            val method = B::class.java.getMethod("bind", View::class.java)
            val viewBinding = method.invoke(null, containView) as B
            this.viewBinding = viewBinding
            viewBinding
        } else {
            viewBinding as B
        }
    }

    /** 通用的加载视图方法 **/
    private fun loadView(lifecycleOwner: LifecycleOwner?, parentGroup: ViewGroup, asyncLoad: Boolean, completion: (View) -> Unit) {
        if (getLayoutResId() != 0) {
            if (asyncLoad) {
                // 异步加载
                val asyncLayoutInflater = AsyncLayoutInflater(ShatterManager.applicationContext)
                asyncLayoutInflater.inflate(getLayoutResId(), parentGroup) { view, _, _ ->
                    completion(view) // 使用回调返回加载完成的视图
                }
            } else {
                // 同步加载
                lifecycleOwner?.run {
                    val view = LayoutInflater.from(ShatterManager.applicationContext).inflate(getLayoutResId(), parentGroup, false)
                    completion(view) // 使用回调返回加载完成的视图
                }
            }
        }
    }

    /** 预加载 **/
    fun preload(lifecycleOwner: LifecycleOwner?, asyncLoad: Boolean) {
        this.lifecycleOwner = lifecycleOwner

        if (!isPreloading) {
            isPreloading = true
            loadView(lifecycleOwner, RelativeLayout(ShatterManager.applicationContext), asyncLoad) { view ->
                // 预加载完成
                preloadedView = view
                isPreloadCompleted = true
                isPreloading = false
                onViewReadyListener?.onViewReady(view)
                "${getTag()} 预加载完成啦".shatterLog()
            }
        }
    }

    /** 绑定Lifecycle，加载布局，添加到容器 **/
    fun attachToLifecycleOwner(lifecycleOwner: LifecycleOwner?, asyncLoad: Boolean, index: Int) {
        this.lifecycleOwner = lifecycleOwner

        if (getLayoutResId() != 0) {

            if (containView != null && containView is ViewGroup) {
                if (preloadedView != null && isPreloadCompleted) {
                    // 如果预加载已完成，则添加到containView
                    addView2Group(preloadedView, index)
                    containView = preloadedView
                    preloadedView = null // 清除引用

                    // 初始化Shatter调用onCreate等方法
                    onShatterCreate(lifecycleOwner)
                } else {
                    // 设置布局加载的监听
                    onViewReadyListener = object : OnViewReadyListener {
                        override fun onViewReady(view: View) {
                            addView2Group(view, index)
                            containView = view
                            // 在添加视图后清除回调，防止内存泄漏
                            onViewReadyListener = null

                            // 初始化Shatter调用onCreate等方法
                            onShatterCreate(lifecycleOwner)
                        }
                    }

                    // 如果当前没有进行预加载，则启动加载过程
                    if (!isPreloading) {
                        loadView(lifecycleOwner, containView as ViewGroup, asyncLoad) { view ->
                            onViewReadyListener?.onViewReady(view)
                        }
                    }
                }
            }

        } else {
            // 直接初始化无布局的Shatter
            onShatterCreate(lifecycleOwner)
        }
    }

    private fun addView2Group(view: View?, index: Int) {
        thisView = view
        val groupView = containView as ViewGroup
        val childCount = groupView.childCount

        if (view == null) return

        // 如果索引在当前子视图数量的范围内
        if (index < childCount) {
            groupView.removeViewAt(index)
            groupView.addView(view, index)
        } else {
            // 如果索引等于或大于当前子视图数量，添加空视图作为占位符，直到达到指定的索引，然后添加目标视图
            for (i in childCount until index) {
                groupView.addView(View(ShatterManager.applicationContext).apply {
                    visibility = View.INVISIBLE
                })
            }
            groupView.addView(view, index)
        }

    }

    /** 当碎片被创建时调用 **/
    private fun onShatterCreate(lifecycleOwner: LifecycleOwner?) {
        if (lifecycleOwner is FragmentActivity) {
            val activity = lifecycleOwner
            onCreate(activity.intent)
            initView(containView, activity.intent)
            initData(activity.intent)

        } else if (lifecycleOwner is Fragment) {
            onCreate(null)
            initView(containView, null)
            initData(null)
        }

    }

    /** 获取布局资源ID **/
    @LayoutRes
    abstract fun getLayoutResId(): Int

    /** 获取碎片标签 **/
    open fun getTag(): String = this::class.java.simpleName

    /** 查找指定类型的碎片 **/
    open fun <T : Shatter> findShatter(clazz: Class<T>): T? {
        val tag = clazz.simpleName
        val shatter = shatterManager?.cache?.getShatter(tag)
        if (shatter != null) {
            @Suppress("UNCHECKED_CAST")
            return shatter as T
        }
        return null
    }

    /** 发送碎片事件 **/
    open fun sendShatterEvent(key: String, data: Any? = null) {
        shatterManager?.sendShatterEvent(key, data)
    }

    /** 接收处理碎片事件 **/
    open fun onShatterEvent(key: String, data: Any?) {
    }

    open fun onCreate(intent: Intent?) {}

    open fun initView(view: View?, intent: Intent?) {}

    /** 初始化数据 **/
    open fun initData(intent: Intent?) {}

    /** 处理新的Intent **/
    override fun onNewIntent(intent: Intent?) {
    }

    /** 保存实例状态 **/
    override fun onSaveInstanceState(outState: Bundle?) {
    }

    /** 恢复实例状态 **/
    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
    }

    override fun onStart() {
    }

    open fun onRestart() {

    }

    override fun onResume() {

    }

    override fun onPause() {
    }

    override fun onStop() {
    }

    override fun onDestroy() {
    }

    /** 处理ActivityResult **/
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

    }

    /** 是否允许返回键 **/
    override fun enableOnBackPressed(): Boolean = true

    /** Fragment 是否可见 **/
    override fun onHiddenChanged(isHidden: Boolean) {
    }

    /** 给ShatterManager遍历调用 **/
    fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
    }

    override val lifecycle: Lifecycle
        get() = lifecycleOwner!!.lifecycle

}
